package com.lwl.concurrency.synchr;

import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 一个ReentrantLock实例对象的lock()和unlock()方法,同一时间只能被一条线程配合使用
 * 一个线程可以同一时间可以连续两次获取ReentrantLock锁,所以叫做重入锁,否则会产生死锁
 *
 * @author liwenlong - 2018/3/27 13:49
 */
public class ReentrantLockTest {

    public ReentrantLock lock = new ReentrantLock();
    public static int i = 0;

    public void lockRun1() {
        try {
            lock.lock();
            System.out.println(Thread.currentThread().getName()+" lockRun1 "+ LocalDateTime.now().toString());
            TimeUnit.SECONDS.sleep(5);
            for (int j = 0; j < 10000000; j++) {
                i++;
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void lockRun2() {
        try {
            lock.lock();
            System.out.println(Thread.currentThread().getName()+" lockRun2 "+ LocalDateTime.now().toString());
            TimeUnit.SECONDS.sleep(5);
            for (int j = 0; j < 10000000; j++) {
                i++;
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        ReentrantLockTest lockTest = new ReentrantLockTest();
        Thread thread1 = new Thread(lockTest::lockRun1);
        Thread thread2 = new Thread(lockTest::lockRun1);

        new Thread(lockTest::lockRun2).start();
        new Thread(lockTest::lockRun2).start();

        long start = System.currentTimeMillis();

        thread1.start();
        thread2.start();
        thread1.join();
        thread2.join();

        System.out.println("耗时:" + (System.currentTimeMillis() - start));
        System.out.println("结果:" + i);
    }


}
